/**
 * 权限管理工具
 */

/**
 * 权限类型定义
 */
export interface Permission {
  id: string;
  name: string;
  code: string;
  type: 'menu' | 'button' | 'api';
  parentId?: string;
  children?: Permission[];
}

/**
 * 角色类型定义
 */
export interface Role {
  id: string;
  name: string;
  code: string;
  permissions: string[]; // 权限ID数组
}

/**
 * 用户权限信息
 */
export interface UserPermission {
  userId: string;
  roles: Role[];
  permissions: Permission[];
}

/**
 * 权限管理器类
 */
export class PermissionManager {
  private userPermissions: UserPermission | null = null;
  private permissionCache = new Map<string, boolean>();

  /**
   * 设置用户权限信息
   * @param userPermissions 用户权限信息
   */
  setUserPermissions(userPermissions: UserPermission): void {
    this.userPermissions = userPermissions;
    this.permissionCache.clear(); // 清空缓存
  }

  /**
   * 获取用户权限信息
   * @returns 用户权限信息
   */
  getUserPermissions(): UserPermission | null {
    return this.userPermissions;
  }

  /**
   * 检查用户是否有指定权限
   * @param permissionCode 权限代码
   * @returns 是否有权限
   */
  hasPermission(permissionCode: string): boolean {
    if (!this.userPermissions) return false;

    // 检查缓存
    if (this.permissionCache.has(permissionCode)) {
      return this.permissionCache.get(permissionCode)!;
    }

    const hasPermission = this.checkPermission(permissionCode);
    this.permissionCache.set(permissionCode, hasPermission);
    return hasPermission;
  }

  /**
   * 检查用户是否有指定角色
   * @param roleCode 角色代码
   * @returns 是否有角色
   */
  hasRole(roleCode: string): boolean {
    if (!this.userPermissions) return false;
    return this.userPermissions.roles.some(role => role.code === roleCode);
  }

  /**
   * 检查用户是否有任意一个指定角色
   * @param roleCodes 角色代码数组
   * @returns 是否有任意一个角色
   */
  hasAnyRole(roleCodes: string[]): boolean {
    if (!this.userPermissions) return false;
    return this.userPermissions.roles.some(role => roleCodes.includes(role.code));
  }

  /**
   * 检查用户是否有所有指定角色
   * @param roleCodes 角色代码数组
   * @returns 是否有所有角色
   */
  hasAllRoles(roleCodes: string[]): boolean {
    if (!this.userPermissions) return false;
    return roleCodes.every(roleCode => 
      this.userPermissions!.roles.some(role => role.code === roleCode)
    );
  }

  /**
   * 获取用户所有权限代码
   * @returns 权限代码数组
   */
  getAllPermissions(): string[] {
    if (!this.userPermissions) return [];
    return this.userPermissions.permissions.map(p => p.code);
  }

  /**
   * 获取用户所有角色代码
   * @returns 角色代码数组
   */
  getAllRoles(): string[] {
    if (!this.userPermissions) return [];
    return this.userPermissions.roles.map(r => r.code);
  }

  /**
   * 检查权限的具体实现
   * @param permissionCode 权限代码
   * @returns 是否有权限
   */
  private checkPermission(permissionCode: string): boolean {
    if (!this.userPermissions) return false;

    // 直接检查权限
    const hasDirectPermission = this.userPermissions.permissions.some(
      p => p.code === permissionCode
    );

    if (hasDirectPermission) return true;

    // 通过角色检查权限
    const hasRolePermission = this.userPermissions.roles.some(role =>
      role.permissions.some(permissionId => {
        const permission = this.findPermissionById(permissionId);
        return permission && permission.code === permissionCode;
      })
    );

    return hasRolePermission;
  }

  /**
   * 根据ID查找权限
   * @param permissionId 权限ID
   * @returns 权限对象
   */
  private findPermissionById(permissionId: string): Permission | undefined {
    if (!this.userPermissions) return undefined;

    const findInPermissions = (permissions: Permission[]): Permission | undefined => {
      for (const permission of permissions) {
        if (permission.id === permissionId) {
          return permission;
        }
        if (permission.children) {
          const found = findInPermissions(permission.children);
          if (found) return found;
        }
      }
      return undefined;
    };

    return findInPermissions(this.userPermissions.permissions);
  }

  /**
   * 清空权限信息
   */
  clearPermissions(): void {
    this.userPermissions = null;
    this.permissionCache.clear();
  }
}

/**
 * 全局权限管理器实例
 */
export const permissionManager = new PermissionManager();

/**
 * 权限检查装饰器（用于方法）
 * @param permissionCode 权限代码
 * @returns 装饰器函数
 */
export function RequirePermission(permissionCode: string) {
  return function (_target: any, _propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;

    descriptor.value = function (...args: any[]) {
      if (!permissionManager.hasPermission(permissionCode)) {
        throw new Error(`权限不足：需要 ${permissionCode} 权限`);
      }
      return originalMethod.apply(this, args);
    };

    return descriptor;
  };
}

/**
 * 角色检查装饰器（用于方法）
 * @param roleCode 角色代码
 * @returns 装饰器函数
 */
export function RequireRole(roleCode: string) {
  return function (_target: any, _propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;

    descriptor.value = function (...args: any[]) {
      if (!permissionManager.hasRole(roleCode)) {
        throw new Error(`权限不足：需要 ${roleCode} 角色`);
      }
      return originalMethod.apply(this, args);
    };

    return descriptor;
  };
}

/**
 * Vue 3 权限指令
 */
export const permissionDirective = {
  mounted(el: HTMLElement, binding: any) {
    const { value } = binding;
    if (!value) return;

    let hasPermission = false;

    if (typeof value === 'string') {
      hasPermission = permissionManager.hasPermission(value);
    } else if (Array.isArray(value)) {
      hasPermission = value.some((code: string) => permissionManager.hasPermission(code));
    } else if (typeof value === 'object') {
      const { permission, role, anyRole, allRoles } = value;
      
      if (permission) {
        hasPermission = permissionManager.hasPermission(permission);
      } else if (role) {
        hasPermission = permissionManager.hasRole(role);
      } else if (anyRole) {
        hasPermission = permissionManager.hasAnyRole(anyRole);
      } else if (allRoles) {
        hasPermission = permissionManager.hasAllRoles(allRoles);
      }
    }

    if (!hasPermission) {
      el.style.display = 'none';
    }
  },
  updated(el: HTMLElement, binding: any) {
    // 更新时重新检查权限
    permissionDirective.mounted(el, binding);
  }
};

/**
 * 权限检查组合式函数
 * @returns 权限检查相关方法
 */
export function usePermission() {
  /**
   * 检查权限
   * @param permissionCode 权限代码
   * @returns 是否有权限
   */
  const hasPermission = (permissionCode: string): boolean => {
    return permissionManager.hasPermission(permissionCode);
  };

  /**
   * 检查角色
   * @param roleCode 角色代码
   * @returns 是否有角色
   */
  const hasRole = (roleCode: string): boolean => {
    return permissionManager.hasRole(roleCode);
  };

  /**
   * 检查任意角色
   * @param roleCodes 角色代码数组
   * @returns 是否有任意一个角色
   */
  const hasAnyRole = (roleCodes: string[]): boolean => {
    return permissionManager.hasAnyRole(roleCodes);
  };

  /**
   * 检查所有角色
   * @param roleCodes 角色代码数组
   * @returns 是否有所有角色
   */
  const hasAllRoles = (roleCodes: string[]): boolean => {
    return permissionManager.hasAllRoles(roleCodes);
  };

  /**
   * 获取所有权限
   * @returns 权限代码数组
   */
  const getAllPermissions = (): string[] => {
    return permissionManager.getAllPermissions();
  };

  /**
   * 获取所有角色
   * @returns 角色代码数组
   */
  const getAllRoles = (): string[] => {
    return permissionManager.getAllRoles();
  };

  return {
    hasPermission,
    hasRole,
    hasAnyRole,
    hasAllRoles,
    getAllPermissions,
    getAllRoles
  };
}

/**
 * 路由权限守卫
 * @param to 目标路由
 * @param from 来源路由
 * @param next 路由跳转函数
 */
export function permissionGuard(to: any, _from: any, next: any) {
  const requiredPermission = to.meta?.permission;
  const requiredRole = to.meta?.role;
  const requiredAnyRole = to.meta?.anyRole;
  const requiredAllRoles = to.meta?.allRoles;

  if (requiredPermission && !permissionManager.hasPermission(requiredPermission)) {
    next('/403'); // 跳转到403页面
    return;
  }

  if (requiredRole && !permissionManager.hasRole(requiredRole)) {
    next('/403');
    return;
  }

  if (requiredAnyRole && !permissionManager.hasAnyRole(requiredAnyRole)) {
    next('/403');
    return;
  }

  if (requiredAllRoles && !permissionManager.hasAllRoles(requiredAllRoles)) {
    next('/403');
    return;
  }

  next();
}

/**
 * 权限工具函数
 */
export const permissionUtils = {
  /**
   * 检查权限
   * @param permissionCode 权限代码
   * @returns 是否有权限
   */
  hasPermission: (permissionCode: string) => permissionManager.hasPermission(permissionCode),

  /**
   * 检查角色
   * @param roleCode 角色代码
   * @returns 是否有角色
   */
  hasRole: (roleCode: string) => permissionManager.hasRole(roleCode),

  /**
   * 检查任意角色
   * @param roleCodes 角色代码数组
   * @returns 是否有任意一个角色
   */
  hasAnyRole: (roleCodes: string[]) => permissionManager.hasAnyRole(roleCodes),

  /**
   * 检查所有角色
   * @param roleCodes 角色代码数组
   * @returns 是否有所有角色
   */
  hasAllRoles: (roleCodes: string[]) => permissionManager.hasAllRoles(roleCodes),

  /**
   * 设置用户权限
   * @param userPermissions 用户权限信息
   */
  setUserPermissions: (userPermissions: UserPermission) => permissionManager.setUserPermissions(userPermissions),

  /**
   * 清空权限
   */
  clearPermissions: () => permissionManager.clearPermissions()
};
